package com.example.demo.service;

import com.example.demo.entity.SaleOrder;
import com.example.demo.entity.SaleOrderItem;
import com.example.demo.entity.Inventory;
import com.example.demo.repository.SaleOrderRepository;
import com.example.demo.repository.SaleOrderItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * 销售订单服务类
 */
@Service
@Transactional
public class SaleOrderService {
    
    @Autowired
    private SaleOrderRepository saleOrderRepository;
    
    @Autowired
    private SaleOrderItemRepository saleOrderItemRepository;
    
    @Autowired
    private InventoryService inventoryService;
    
    public SaleOrder save(SaleOrder saleOrder) {
        return saleOrderRepository.save(saleOrder);
    }
    
    public Optional<SaleOrder> findById(Long id) {
        return saleOrderRepository.findById(id);
    }
    
    public Optional<SaleOrder> findByOrderNumber(String orderNumber) {
        return saleOrderRepository.findByOrderNumber(orderNumber);
    }
    
    public List<SaleOrder> findByCustomerId(Long customerId) {
        return saleOrderRepository.findByCustomerId(customerId);
    }
    
    public List<SaleOrder> findByCashierId(Long cashierId) {
        return saleOrderRepository.findByCashierId(cashierId);
    }
    
    public List<SaleOrder> findByStatus(SaleOrder.OrderStatus status) {
        return saleOrderRepository.findByStatus(status);
    }
    
    public List<SaleOrder> findByOrderTimeBetween(LocalDateTime startTime, LocalDateTime endTime) {
        return saleOrderRepository.findByOrderTimeBetween(startTime, endTime);
    }
    
    public List<SaleOrder> findByCashierIdAndOrderTimeBetween(Long cashierId, LocalDateTime startTime, LocalDateTime endTime) {
        return saleOrderRepository.findByCashierIdAndOrderTimeBetween(cashierId, startTime, endTime);
    }
    
    public Double getTotalSalesByDateRange(LocalDateTime startTime, LocalDateTime endTime) {
        return saleOrderRepository.getTotalSalesByDateRange(startTime, endTime);
    }
    
    public boolean existsByOrderNumber(String orderNumber) {
        return saleOrderRepository.existsByOrderNumber(orderNumber);
    }
    
    /**
     * 创建销售订单
     */
    public SaleOrder createOrder(SaleOrder order, List<SaleOrderItem> items) {
        // 生成订单号
        String orderNumber = generateOrderNumber();
        order.setOrderNumber(orderNumber);
        order.setOrderTime(LocalDateTime.now());
        order.setStatus(SaleOrder.OrderStatus.PENDING);
        
        // 计算总金额
        BigDecimal totalAmount = items.stream()
                .map(SaleOrderItem::getTotalPrice)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        order.setTotalAmount(totalAmount);
        order.setFinalAmount(totalAmount.subtract(order.getDiscountAmount()));
        
        // 保存订单
        SaleOrder savedOrder = saleOrderRepository.save(order);
        
        // 保存订单明细
        for (SaleOrderItem item : items) {
            item.setOrderId(savedOrder.getId());
            saleOrderItemRepository.save(item);
        }
        
        return savedOrder;
    }
    
    /**
     * 确认订单
     */
    public SaleOrder confirmOrder(Long orderId) {
        Optional<SaleOrder> orderOpt = findById(orderId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        SaleOrder order = orderOpt.get();
        if (order.getStatus() != SaleOrder.OrderStatus.PENDING) {
            throw new RuntimeException("订单状态不正确");
        }
        
        // 检查库存并预留
        List<SaleOrderItem> items = saleOrderItemRepository.findByOrderId(orderId);
        for (SaleOrderItem item : items) {
            // 这里需要根据实际业务逻辑确定仓库ID
            Long warehouseId = 1L; // 默认仓库
            inventoryService.reserve(item.getProductId(), warehouseId, item.getQuantity());
        }
        
        order.setStatus(SaleOrder.OrderStatus.CONFIRMED);
        return saleOrderRepository.save(order);
    }
    
    /**
     * 完成订单
     */
    public SaleOrder completeOrder(Long orderId) {
        Optional<SaleOrder> orderOpt = findById(orderId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        SaleOrder order = orderOpt.get();
        if (order.getStatus() != SaleOrder.OrderStatus.CONFIRMED) {
            throw new RuntimeException("订单状态不正确");
        }
        
        // 扣减库存
        List<SaleOrderItem> items = saleOrderItemRepository.findByOrderId(orderId);
        for (SaleOrderItem item : items) {
            Long warehouseId = 1L; // 默认仓库
            inventoryService.outbound(item.getProductId(), warehouseId, item.getQuantity());
        }
        
        order.setStatus(SaleOrder.OrderStatus.COMPLETED);
        return saleOrderRepository.save(order);
    }
    
    /**
     * 取消订单
     */
    public SaleOrder cancelOrder(Long orderId) {
        Optional<SaleOrder> orderOpt = findById(orderId);
        if (!orderOpt.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        
        SaleOrder order = orderOpt.get();
        if (order.getStatus() == SaleOrder.OrderStatus.COMPLETED) {
            throw new RuntimeException("已完成的订单不能取消");
        }
        
        // 如果已确认，需要释放预留库存
        if (order.getStatus() == SaleOrder.OrderStatus.CONFIRMED) {
            List<SaleOrderItem> items = saleOrderItemRepository.findByOrderId(orderId);
            for (SaleOrderItem item : items) {
                Long warehouseId = 1L; // 默认仓库
                inventoryService.release(item.getProductId(), warehouseId, item.getQuantity());
            }
        }
        
        order.setStatus(SaleOrder.OrderStatus.CANCELLED);
        return saleOrderRepository.save(order);
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderNumber() {
        return "SO" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 6).toUpperCase();
    }
    
    public void deleteById(Long id) {
        saleOrderRepository.deleteById(id);
    }
    
    public SaleOrder update(SaleOrder saleOrder) {
        return saleOrderRepository.save(saleOrder);
    }
}
